// import 'reflect-metadata';

// /**
//  * 属性装饰器的签名为 (target: Object, propertyKey: string | symbol) => void。
//  * 它接受两个参数：
//  * target: Object - 装饰器应用于的类的原型。
//  * propertyKey: string | symbol - 被装饰的属性的名称或符号。
//  * 属性装饰器通常用于修改类的属性的元数据或行为。
//  * 它们可以用于添加验证规则、序列化规则、默认值等。
//  * 例如，@IsString() 装饰器可以用于验证属性是否为字符串类型。
//  * @param target - 装饰的目标对象，对于静态成员来说是类的构造函数，对于实例成员是类的原型对象。
//  * @param propertyKey - 装饰的成员名称。
//  *
//  */
// //定义必传属性的函数
// function required(target: any, propertyKey: string) {
//   // Reflect.getMetadata('required', target, propertyKey) 用于获取指定元数据的值。
//   // 第一个参数是元数据的键名，第二个参数是元数据的目标对象，第三个参数是元数据的属性名。
//   //在目标对象上定义一个名为 required 的元数据，值为 true。
//   Reflect.defineMetadata('required', true, target, propertyKey);
// }
// function validator(user: User) {
//   for (let key in user) {
//     // Reflect.getMetadata('required', user, key) 用于获取指定元数据的值。
//     // 第一个参数是元数据的键名，第二个参数是元数据的目标对象，第三个参数是元数据的属性名。
//     // 如果元数据的值为 true，则抛出一个错误，提示该属性是必填的。
//     // 如果元数据的值为 false，则不做任何操作。
//     if (Reflect.getMetadata('required', user, key) && !user[key]) {
//       throw new Error(`${key} is required`);
//     }
//   }
// }
// class User {
//   constructor(username: string) {
//     this.username = username;
//   }
//   @required
//   username: string;
// }
// const zs = new User('zs');
// //在类的实例上定义一个名为 username 的元数据，值为 'zs'。
// zs.username = 'zs';
// validator(zs);

// //可以使用属性装饰器来定义属性的访问控制或初始值设置。

// /**
//  * 属性装饰器工厂函数，用于为类的属性设置默认值
//  * @param value - 要设置的默认值，类型为字符串
//  * @returns 返回一个属性装饰器函数
//  */
// // function defaultValue(value: any) {
// //   // 返回一个属性装饰器函数
// //   return function (target: any, propKey: string) {
// //     // 初始化属性值为传入的默认值
// //     let val = value;

// //     /**
// //      * 获取属性值的 getter 函数
// //      * @returns 返回属性当前的值
// //      */
// //     const getter = function () {
// //       return val;
// //     };

// //     /**
// //      * 设置属性值的 setter 函数
// //      * @param newVal - 要设置的新值
// //      */
// //     const setter = function (newVal) {
// //       val = newVal;
// //     };

// //     // 在目标对象的原型上定义属性
// //     Object.defineProperty(target, propKey, {
// //       // 该属性可被 for...in 循环和 Object.keys() 枚举
// //       enumerable: true,
// //       // 该属性的描述符可以被修改，也可以被删除
// //       configurable: true,
// //       // 使用定义的 getter 函数获取属性值
// //       get: getter,
// //       // 使用定义的 setter 函数设置属性值
// //       set: setter,
// //     });
// //   };
// // }
// function defaultValue(value: any) {
//   return function (constructor: any) {
//     return class extends constructor {
//       constructor() {
//         super();
//         Object.keys(defaultValue).forEach((key) => {
//           if (!this[key]) {
//             this[key] = value[key];
//           }
//         });
//       }
//     };
//   };
// }
// @defaultValue({
//   theme: dark,
// })
// class Settings {
//   @defaultValue('dark')
//   theme: string;
// }

// const s1 = new Settings();
// console.log(
//   Object.getOwnPropertyDescriptor(Object.getPrototypeOf(s1), 'theme'),
// ); //有值
// console.log(Object.getOwnPropertyDescriptor(s1, 'theme')); //undefined
// console.log(s1.theme, '--theme'); //dark --theme

// /**
//  * 2.2.5.4 注意事项
// 不可直接修改属性值： 属性装饰器不能直接修改属性值或描述符，只能用于添加元数据或做一些初始化操作。

// 配合其他装饰器使用： 属性装饰器通常与其他类型的装饰器（如方法装饰器、类装饰器）配合使用，以实现更复杂的功能。
//  */
